package com.lineage.server.model;

import com.lineage.server.model.Instance.L1DollInstance;
import com.lineage.server.model.Instance.L1NpcInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public abstract class L1MagicMode {
  private static final Log _log = LogFactory.getLog(L1MagicMode.class);
  
  protected static final Random _random = new Random();
  
  protected L1PcInstance _pc = null;
  
  protected L1PcInstance _targetPc = null;
  
  protected L1NpcInstance _npc = null;
  
  protected L1NpcInstance _targetNpc = null;
  
  protected int _leverage = 10;
  
  protected int _calcType;
  
  protected static final int PC_PC = 1;
  
  protected static final int PC_NPC = 2;
  
  protected static final int NPC_PC = 3;
  
  protected static final int NPC_NPC = 4;
  
  protected static boolean dmg0(L1Character character) {
    try {
      if (character == null)
        return false; 
      if (character.getSkillisEmpty())
        return false; 
      if (character.getSkillEffect().size() <= 0)
        return false; 
      Iterator<Integer> iterator = character.getSkillEffect().iterator();
      while (iterator.hasNext()) {
        Integer key = iterator.next();
        Integer integer = L1AttackList.SKM0.get(key);
        if (integer != null)
          return true; 
      } 
    } catch (ConcurrentModificationException concurrentModificationException) {
    
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return false;
    } 
    return false;
  }
  
  protected static double getDamageUpByClan(L1PcInstance pc) {
    double dmg = 0.0D;
    try {
      if (pc == null)
        return 0.0D; 
      dmg += pc.get_magic_modifier_dmg();
      L1Clan clan = pc.getClan();
      if (clan == null)
        return dmg; 
      if (clan.isClanskill() && pc.get_other().get_clanskill() == 4) {
        int clanMan = clan.getOnlineClanMemberSize();
        dmg += 0.25D * clanMan;
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return 0.0D;
    } 
    return dmg;
  }
  
  protected static double getDamageReductionByClan(L1PcInstance targetPc) {
    double dmg = 0.0D;
    try {
      if (targetPc == null)
        return 0.0D; 
      dmg += targetPc.get_magic_reduction_dmg();
      L1Clan clan = targetPc.getClan();
      if (clan == null)
        return 0.0D; 
      if (clan.isClanskill() && targetPc.get_other().get_clanskill() == 8) {
        int clanMan = clan.getOnlineClanMemberSize();
        dmg += 0.25D * clanMan;
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return 0.0D;
    } 
    return dmg;
  }
  
  public void setLeverage(int i) {
    this._leverage = i;
  }
  
  protected int getLeverage() {
    return this._leverage;
  }
  
  protected int getTargetSp() {
    int sp = 0;
    switch (this._calcType) {
      case 1:
      case 2:
        sp = this._pc.getSp() - this._pc.getTrueSp();
        switch (this._pc.guardianEncounter()) {
          case 3:
            sp++;
            break;
          case 4:
            sp += 2;
            break;
          case 5:
            sp += 3;
            break;
        } 
        break;
      case 3:
      case 4:
        sp = this._npc.getSp() - this._npc.getTrueSp();
        break;
    } 
    return sp;
  }
  
  protected int getTargetMr() {
    int mr = 0;
    switch (this._calcType) {
      case 1:
      case 3:
        if (this._targetPc == null)
          return 0; 
        mr = this._targetPc.getMr();
        switch (this._targetPc.guardianEncounter()) {
          case 0:
            mr += 3;
            break;
          case 1:
            mr += 6;
            break;
          case 2:
            mr += 9;
            break;
        } 
        break;
      case 2:
      case 4:
        if (this._targetNpc == null)
          return 0; 
        mr = this._targetNpc.getMr();
        break;
    } 
    return mr;
  }
  
  protected boolean calcEvasion() {
    if (this._targetPc == null)
      return false; 
    int ev = this._targetPc.get_evasion();
    if (ev == 0)
      return false; 
    int rnd = _random.nextInt(1000) + 1;
    if (rnd <= ev) {
      if (!this._targetPc.getDolls().isEmpty()) {
        Iterator<L1DollInstance> iterator = this._targetPc.getDolls().values().iterator();
        while (iterator.hasNext()) {
          L1DollInstance doll = iterator.next();
          doll.show_action(2);
        } 
      } 
      return true;
    } 
    return false;
  }
  
  protected double calcAttrResistance(int attr) {
    int resist = 0;
    switch (this._calcType) {
      case 1:
      case 3:
        if (this._targetPc == null)
          return 0.0D; 
        switch (attr) {
          case 1:
            resist = this._targetPc.getEarth();
            break;
          case 2:
            resist = this._targetPc.getFire();
            break;
          case 4:
            resist = this._targetPc.getWater();
            break;
          case 8:
            resist = this._targetPc.getWind();
            break;
        } 
      case 2:
      case 4:
        if (this._targetNpc == null)
          return 0.0D; 
        switch (attr) {
          case 1:
            resist = this._targetNpc.getEarth();
            break;
          case 2:
            resist = this._targetNpc.getFire();
            break;
          case 4:
            resist = this._targetNpc.getWater();
            break;
          case 8:
            resist = this._targetNpc.getWind();
            break;
        } 
        break;
    } 
    int resistFloor = (int)(0.16D * Math.abs(resist));
    if (resist >= 0) {
      resistFloor *= 1;
    } else {
      resistFloor *= -1;
    } 
    double attrDeffence = resistFloor / 32.0D;
    return attrDeffence;
  }
  
  public abstract boolean calcProbabilityMagic(int paramInt);
  
  public abstract int calcMagicDamage(int paramInt);
  
  public abstract int calcHealing(int paramInt);
  
  public abstract void commit(int paramInt1, int paramInt2);
}
